﻿using XiaLastorm.Sharpshooter;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.Collections.Generic;

namespace TestProject1
{
	
	
	/// <summary>
	///这是 MessageTest 的测试类，旨在
	///包含所有 MessageTest 单元测试
	///</summary>
	[TestClass()]
	public class MessageTest
	{


		private TestContext testContextInstance;

		/// <summary>
		///获取或设置测试上下文，上下文提供
		///有关当前测试运行及其功能的信息。
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region 附加测试特性
		// 
		//编写测试时，还可使用以下特性:
		//
		//使用 ClassInitialize 在运行类中的第一个测试前先运行代码
		//[ClassInitialize()]
		//public static void MyClassInitialize(TestContext testContext)
		//{
		//}
		//
		//使用 ClassCleanup 在运行完类中的所有测试后再运行代码
		//[ClassCleanup()]
		//public static void MyClassCleanup()
		//{
		//}
		//
		//使用 TestInitialize 在运行每个测试前先运行代码
		//[TestInitialize()]
		//public void MyTestInitialize()
		//{
		//}
		//
		//使用 TestCleanup 在运行完每个测试后运行代码
		//[TestCleanup()]
		//public void MyTestCleanup()
		//{
		//}
		//
		#endregion

		public readonly Message[] Messages;

		public MessageTest()
		{
			List<Message> messages = new List<Message>();
			messages.Add(new ChatMessage(new User("from"), new User("to"), System.Text.Encoding.Unicode.GetBytes("content")));
			messages.Add(new ClientQuitMessage());
			messages.Add(new ErrorMessage("错误信息", new LogInMessage("Username", "Password")));
			messages.Add(new LogInMessage("Username", "Password"));
			messages.Add(new LogInResultMessage(null));
			messages.Add(new LogInResultMessage(new User("Username")));
			messages.Add(new LogOutMessage());
			messages.Add(new LogOutResultMessage(true));
			messages.Add(new LogOutResultMessage(false));
			List<User> friends = new List<User>();
			friends.Add(new User("friend1"));
			friends.Add(new User("friend2"));
			messages.Add(new RefreshFriendsListMessage(friends));
			Messages = messages.ToArray();
		}

		public static bool MessageEqual(Message left, Message right)
		{
			if (left == null || right == null)
			{
				return false;
			}
			else if (left.GetType() != right.GetType())
			{
				return false;
			}
			else if (left.GetType() == typeof(ChatMessage))
			{
				var left2 = left as ChatMessage;
				var right2 = right as ChatMessage;
				return left2.From == right2.From && left2.To == right2.To && left2.Content.SequenceEqual(right2.Content);
			}
			else if (left.GetType() == typeof(ClientQuitMessage))
			{
				var left2 = left as ClientQuitMessage;
				var right2 = right as ClientQuitMessage;
				return true;
			}
			else if (left.GetType() == typeof(ErrorMessage))
			{
				var left2 = left as ErrorMessage;
				var right2 = right as ErrorMessage;
				return left2.Error == right2.Error && MessageEqual(left2.MessageToCauseError, right2.MessageToCauseError);
			}
			else if (left.GetType() == typeof(LogInMessage))
			{
				var left2 = left as LogInMessage;
				var right2 = right as LogInMessage;
				return left2.Username == right2.Username && left2.Password == right2.Password;
			}
			else if (left.GetType() == typeof(LogInResultMessage))
			{
				var left2 = left as LogInResultMessage;
				var right2 = right as LogInResultMessage;
				return left2.IsLoggedIn == right2.IsLoggedIn && left2.User == right2.User;
			}
			else if (left.GetType() == typeof(LogOutMessage))
			{
				var left2 = left as LogOutMessage;
				var right2 = right as LogOutMessage;
				return true;
			}
			else if (left.GetType() == typeof(LogOutResultMessage))
			{
				var left2 = left as LogOutResultMessage;
				var right2 = right as LogOutResultMessage;
				return left2.IsLoggedOut == right2.IsLoggedOut;
			}
			else if (left.GetType() == typeof(RefreshFriendsListMessage))
			{
				var left2 = left as RefreshFriendsListMessage;
				var right2 = right as RefreshFriendsListMessage;
				HashSet<User> leftSet = new HashSet<User>(left2.Friends);
				HashSet<User> rightSet = new HashSet<User>(right2.Friends);
				return leftSet.SetEquals(rightSet);
			}
			else
			{
				throw new Exception("没有编写对这种消息的相等判断。消息类型：" + left.GetType().ToString());
			}
		}

		/// <summary>
		///序列化测试
		///</summary>
		[TestMethod()]
		public void SerializationTest()
		{
			foreach (var origin in Messages)
			{
				byte[] bytes = origin.ToBytes();
				Message newMessage = Message.FromBytes(bytes);
				Assert.IsTrue(MessageEqual(origin, newMessage));
			}
		}
	}
}
